<?php defined('BASEPATH') or die('No direct script access.');
/*
 *     Библиотека авторизации включает в себя возможности
 *     не только автоматической авторизации но и проверку
 *     прав доступа.
 * 
 *     Для работы необходимы две таблицы.

    Таблица пользователей
    
        CREATE TABLE users (
              id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
              class_id INTEGER UNSIGNED NOT NULL,
              nick VARCHAR(255) NULL,
              passw VARCHAR(255) NULL,
              PRIMARY KEY(id, class_id),
              INDEX users_FKIndex1(class_id)
        );

    Таблица классов пользователей

        CREATE TABLE class (
              id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
              name VARCHAR(255) NULL,
              description VARCHAR(255) NULL,
              PRIMARY KEY(id)
        );
*/
class Auth
{
    protected $authorised = false;
    protected $privilegies_table;
    protected $CI = null;
    protected $user;
    protected $config;
    public $error='';


    public function __construct()
    {
        //    получаем суперобъект
        $this->CI =& get_instance();
        
        //    массив данных юзера
        $this->user = array(
            'userID' => 0,
            'nick' => '',
            'passw' => '',
            'class' => '',
            'class_desc' => '',
            'access' => false
        );
        
        
        //    устанавливаем дефолтовый конфиг авторизации
        $this->SetAuthConfig();
        //    проверяем авторизацию
        $this->CheckAuth();
        //    загружаем таблицу прав
        $this->CI->load->config('auth_access');
        //    устанавливаем таблицу прав
        $this->SetAccessTable($this->CI->config->item('uaccess'));
    }
    
    //-------------------------------------------------------------------------
    
    /*
     *     Возвращаем информацию о пользователе
     * */
    public function getUser()
    {
        return $this->user;
    }
    
    //-------------------------------------------------------------------------
    
    /*
     *     Функция возвращает авторизирован ли юзер
     * */
    public function isAuthorised()
    {
        return $this->authorised;
    }
    
    //-------------------------------------------------------------------------
    
    /*
     *     Проверка на доступ юзера к модулю
     * */
    public function hasAccess($modulename, $accesstype = '')
    {
        //    если тип доступа юзера к модулю разрешен возвращаем истину
        if($accesstype != '' && isset($modulename))
        {
            if(    isset($this->privilegies_table[$this->user['class']][$modulename])
                && in_array($accesstype, $this->privilegies_table[$this->user['class']][$modulename]))
            {
                return true;
            }
            else return false;
        }
        //    если доступ юзера к модулю разрешен, возвращаем массив типов доступа
        elseif(isset($modulename))
        {
            if(isset($this->privilegies_table[$this->user['class']][$modulename]))
            {
                $this->user['access'] = $this->privilegies_table[$this->user['class']][$modulename];
                return $this->privilegies_table[$this->user['class']][$modulename];
            }
            else return false;
        }
        else return false;
    }
    
    //-------------------------------------------------------------------------
    
    /*
     *     Установка таблицы прав
     * */
    public function setAccessTable($table)
    {
        if(is_array($table))
        {
            $this->privilegies_table = $table;
        }
    }
    
    //-------------------------------------------------------------------------
    
    /*
     *     Функция устанавливает конфиг авторизации.
     * 
     *     Если аргумент не указан то параметры загружается из конфига
     *     Структура передаваемого конфига:
     *         array(
     *             'auth_nick' => <...>,
     *            'auth_passw' => <...>,
     *            'auth_form_nick' => <...>,
     *            'auth_form_passw' => <...>
     *         )
     * */
    public function setAuthConfig($config_array = '')
    {
        if(is_array($config_array))
        {
            $this->config = array(
                'auth_nick' => $config_array['auth_nick'],
                'auth_passw' => $config_array['auth_passw'],
                'auth_form_nick' => $config_array['auth_form_nick'],
                'auth_form_passw' => $config_array['auth_form_passw']
            );
        }
        else
        {
            $this->CI->config->load('auth_config');
            $this->config = array(
                'auth_nick' => $this->CI->config->item('auth_nick'),
                'auth_passw' => $this->CI->config->item('auth_passw'),
                'auth_form_nick' => $this->CI->config->item('auth_form_nick'),
                'auth_form_passw' => $this->CI->config->item('auth_form_passw')
            );
        }
    }
    
    //-------------------------------------------------------------------------

    /*
     *         Проверка соответствия данных юзера данным в форме или сессии
     * */
    public function checkAuth()
    {
       {
        //    строка выборки данных
        
        $query_string = "
            SELECT 
                u.*, c.name AS classname, c.description AS class_desc
            FROM
                ".$this->CI->db->dbprefix."users u, ".$this->CI->db->dbprefix."class c
            WHERE
                u.userID = %s AND
                c.id = u.class_id
            LIMIT
                1";

        $this->CI->load->library('session');
        $this->CI->load->helper('cookie');
        
        //    если в сессии есть данные
        if    (
                $this->CI->session->userdata('usrTok')
                && $this->CI->session->userdata('usrTokSec')
                && $this->CI->session->userdata('usrId')
            )
        {
            //    подготовка данных для запроса
            $userID = $this->CI->security->xss_clean($this->CI->session->userdata('usrId'));
            //$nick = $this->CI->session->userdata($this->CI->config->item('auth_nick'));
            $passw = $this->CI->security->xss_clean($this->CI->session->userdata('usrTok'));
            $userTokenSecret = $this->CI->security->xss_clean($this->CI->session->userdata('usrTokSec'));
        }
        elseif (get_cookie('usrId') && get_cookie('usrTok') && get_cookie('usrTokSec'))
       {
            $userID = get_cookie('usrId', TRUE);
            $passw = get_cookie('usrTok', TRUE);
            $userTokenSecret = get_cookie('usrTokSec', TRUE);
     
       }
        
        //    или данные отправлены из формы
        elseif    ($this->CI->input->post($this->CI->config->item('auth_form_send')))
        {
            $this->authorised = false;
            redirect('/htlogin/connecttoht/', 'refresh');
            return false;
        }
        //    иначе авторизация не прошла
        else
        {
            $this->authorised = false;
            $this->logout();
            return false;
        }
        
        //    выбираем из таблиц информацию
        //$this->CI->load->database();
        $query_params = array($this->CI->db->escape($userID));
        $str = vsprintf($query_string, $query_params);
        $result = $this->CI->db->query(vsprintf($query_string, $query_params));
        if ($result) $user = $result->row_array();
        
        //    если такой юзер найден
        if($user)
        {
            //    и данные верны
            //if    (
            //        md5($user['UsecCode'].$this->CI->config->item('encryption_key')) == $passw    
            //        && $user['userID'] == $userID
            //    )
            if    ($user['UsecCode'] == $passw    && $user['userID'] == $userID  && $user['securityCode'] == $userTokenSecret )
            {
                //    сохраняем данные в сессии
               // $session_data = array(
               //     $this->CI->config->item('auth_ID') => $user['userID'],
               //     $this->CI->config->item('auth_passw') => md5($user['UsecCode'].$this->CI->config->item('encryption_key')),
               //     $this->CI->config->item('auth_nick') => $user['loginName']
               // );
               // $this->CI->session->set_userdata($session_data);
               
               
                $session_data = array(
                    $this->CI->config->item('auth_ID') => $user['userID'],
                    $this->CI->config->item('auth_nick') => $user['loginName']
                );
               $this->CI->session->set_userdata($session_data);
               
               
               $usrdata = array('usrTok'=>$passw,    'usrTokSec'=>$userTokenSecret, 'usrId'=>$userID);
               $this->CI->session->set_userdata($usrdata);
                
                //    запоминаем данные
                $this->user = array(
                    'userID' => $user['userID'],
                    'loginName' => $user['loginName'],
                    'UsecCode' => $passw,
                    'class' => $user['classname'],
                    'class_desc' => $user['class_desc']
                );
                
                $this->authorised = true;
                return true;
            }
        }
        else
        {
            $this->authorised = false;
            $this->error = "False to login";
            $this->logout();
            return false;
        }
        
        }
        
    }
    
    
    
    
    
    function logout()
    {
        $this->CI->session->sess_destroy();
        $this->CI->load->helper('cookie');
        
        $domain=$this->CI->config->item('cookie_domain'); $path=$this->CI->config->item('cookie_path'); $prefix =$this->CI->config->item('cookie_prefix');
        delete_cookie('usrTok', $domain, $path, $prefix);
        delete_cookie('usrTokSec', $domain, $path, $prefix);
        delete_cookie('usrId', $domain, $path, $prefix);
        
        $this->authorised = false;
    }
    
}
?>